package com.chatmcp.mcprouter.controller;

import com.chatmcp.mcprouter.dto.ProxyInfoDto;
import com.chatmcp.mcprouter.dto.ServerConfigDto;
import com.chatmcp.mcprouter.jsonrpc.Tool;
import com.chatmcp.mcprouter.service.McpClientService;
import com.chatmcp.mcprouter.service.McpServerService;
import com.chatmcp.mcprouter.service.ProxyService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * API控制器
 * 处理MCP API请求
 */
@Slf4j
@RestController
@RequestMapping("/v1")
@RequiredArgsConstructor
public class ApiController {

    private final McpServerService mcpServerService;
    private final McpClientService mcpClientService;
    private final ProxyService proxyService;
    private final ObjectMapper objectMapper;

    /**
     * 列出服务器接口
     *
     * @param request HTTP请求
     * @param body    请求体（可选）
     * @return 服务器列表
     */
    @PostMapping("/list-servers")
    public ResponseEntity<Object> listServers(HttpServletRequest request, @RequestBody(required = false) String body) {
        try {
            // 获取服务器配置列表
            Map<String, ServerConfigDto> serverConfigs = mcpServerService.getAllServerConfigs();
            
            // 提取服务器键列表
            String[] servers = serverConfigs.keySet().toArray(new String[0]);
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("servers", servers);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("Error listing servers", e);
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("error", e.getMessage());
            return ResponseEntity.ok(error);
        }
    }

    /**
     * 列出工具接口
     *
     * @param request HTTP请求
     * @param body    请求体
     * @return 工具列表
     */
    @PostMapping("/list-tools")
    public ResponseEntity<Object> listTools(HttpServletRequest request, @RequestBody Map<String, Object> body) {
        try {
            // 验证和提取服务器键
            String key = validateKey(body);
            if (key == null) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Server key is required");
                return ResponseEntity.ok(error);
            }

            // 获取服务器配置
            ServerConfigDto serverConfig = mcpServerService.getServerConfig(key);
            if (serverConfig == null) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Invalid server key: " + key);
                return ResponseEntity.ok(error);
            }

            // 创建代理信息
            ProxyInfoDto proxyInfo = createProxyInfo(serverConfig, "tools/list", request.getRemoteAddr());

            // 连接MCP服务器
            boolean connected = mcpClientService.connect(serverConfig);
            if (!connected) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Failed to connect to MCP server: " + key);
                return ResponseEntity.ok(error);
            }

            // 获取工具列表
            List<Tool> tools = mcpClientService.listTools();

            // 更新代理信息
            proxyInfo.setResponseResult(tools);
            proxyInfo.setResponseTime(LocalDateTime.now());
            if (proxyInfo.getRequestTime() != null) {
                proxyInfo.setCostTime(
                        java.time.Duration.between(proxyInfo.getRequestTime(), proxyInfo.getResponseTime()).toMillis()
                );
            }
            
            // 记录代理信息
            proxyService.logToolCall(proxyInfo);

            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("tools", tools);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("Error listing tools", e);
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("error", e.getMessage());
            return ResponseEntity.ok(error);
        }
    }

    /**
     * 调用工具接口
     *
     * @param request HTTP请求
     * @param body    请求体
     * @return 工具调用结果
     */
    @PostMapping("/call-tool")
    public ResponseEntity<Object> callTool(HttpServletRequest request, @RequestBody Map<String, Object> body) {
        try {
            // 验证和提取服务器键
            String key = validateKey(body);
            if (key == null) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Server key is required");
                return ResponseEntity.ok(error);
            }

            // 获取工具名称
            String toolName = (String) body.get("tool");
            if (StringUtils.isBlank(toolName)) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Tool name is required");
                return ResponseEntity.ok(error);
            }

            // 获取工具参数
            Map<String, Object> arguments = (Map<String, Object>) body.get("arguments");
            if (arguments == null) {
                arguments = new HashMap<>();
            }

            // 获取服务器配置
            ServerConfigDto serverConfig = mcpServerService.getServerConfig(key);
            if (serverConfig == null) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Invalid server key: " + key);
                return ResponseEntity.ok(error);
            }

            // 创建代理信息
            ProxyInfoDto proxyInfo = createProxyInfo(serverConfig, "tools/call", request.getRemoteAddr());
            proxyInfo.setRequestParams(Map.of("name", toolName, "arguments", arguments));

            // 连接MCP服务器
            boolean connected = mcpClientService.connect(serverConfig);
            if (!connected) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("error", "Failed to connect to MCP server: " + key);
                return ResponseEntity.ok(error);
            }

            // 调用工具
            Tool.CallToolResult result = mcpClientService.callTool(toolName, arguments);

            // 更新代理信息
            proxyInfo.setResponseResult(result);
            proxyInfo.setResponseTime(LocalDateTime.now());
            if (proxyInfo.getRequestTime() != null) {
                proxyInfo.setCostTime(
                        java.time.Duration.between(proxyInfo.getRequestTime(), proxyInfo.getResponseTime()).toMillis()
                );
            }
            
            // 记录代理信息
            proxyService.logToolCall(proxyInfo);

            // 返回结果
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("result", result);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error calling tool", e);
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("error", e.getMessage());
            return ResponseEntity.ok(error);
        }
    }
    
    /**
     * 验证和提取服务器键
     *
     * @param body 请求体
     * @return 服务器键，如果无效则返回null
     */
    private String validateKey(Map<String, Object> body) {
        if (body == null) {
            return null;
        }
        
        // 尝试从请求体中获取键
        String key = (String) body.get("key");
        
        // 如果为空，则尝试从授权头中获取
        if (StringUtils.isBlank(key)) {
            return null;
        }
        
        return key;
    }
    
    /**
     * 创建代理信息对象
     *
     * @param serverConfig  服务器配置
     * @param requestMethod 请求方法
     * @param requestFrom   请求来源
     * @return 代理信息对象
     */
    private ProxyInfoDto createProxyInfo(ServerConfigDto serverConfig, String requestMethod, String requestFrom) {
        return ProxyInfoDto.builder()
                .serverKey(serverConfig.getServerKey())
                .serverUuid(serverConfig.getServerUuid())
                .serverName(serverConfig.getServerName())
                .serverType(serverConfig.getServerType())
                .serverUrl(serverConfig.getServerUrl())
                .serverCommand(serverConfig.getCommand())
                .serverCommandHash(serverConfig.getCommandHash())
                .serverShareProcess(serverConfig.getShareProcess())
                .requestMethod(requestMethod)
                .requestFrom(requestFrom)
                .requestTime(LocalDateTime.now())
                .build();
    }
} 